(ns blade-art-online.core.skills)

; 技能可以生成effect，包含数值化的伤害，hp回复量，mp回复量等
; 技能还可以包含effect生效前，生效后等直接影响对象的函数，比如一些技能可以在攻击前降低对方的防御
; 注意，临时改变数值不能直接修改对象的数值，不然会导致永久生效

(defn safe-effect [effect] (assoc effect :damage 0))

(defn safe-effect? [effect] (< (:damage effect) 1))

(defn transfer-danger-effect 
      [effect]
      (if-not (safe-effect? effect)
              (safe-effect effect)
              effect))

; tested
(defn damage 
 [n life] 
 (let [hp (:hp life)] (assoc life :hp (- hp n))))

(defn percentage
 [per]
 (fn [num] 
     (->> 100
     (/ per)
     (* num)
     int)))

(defn get-str [life] (:str life))

(defn spawn-effect 
      [& {:keys [damage hp mp] :or {damage 0 hp 0 mp 0}}]
      {:damage damage
       :hp hp
       :mp mp})

; tested 
(defn vertical-chop-effect 
 [src]
 (->> ((percentage 50) (get-str src))
      (+ 10)
      (spawn-effect :damage)))

(defn return-it [it] it)

(defn spawn-buff [& {:keys [name before-affect spell]
                      :or   {name          "nil"
                             before-affect return-it
                             spell         return-it}}]
                  
                  {:name          name
                   :before-affect before-affect
                   :spell         spell})

(def buffs 
 {:once-shield 
   (spawn-buff 
     :name "寒冰屏障" 
     ; tested
     :before-affect (fn [{effect :effect :as all}] 
                        (assoc all :effect (transfer-danger-effect effect))))
  :poison 
   (spawn-buff
     :name "毒"
     ; tested
     :spell (fn [{src :src :as all}] 
                (assoc all :src (damage 10 src))))})

(defn spawn-skill 
 [& {:keys [name produce-effect affect]
     :or {name ""
          produce-effect (fn [_] (spawn-effect))
          affect return-it}}]
 {:name name
  :produce-effect produce-effect
  :affect affect})

; tested
(defn add-buff 
 [buff-key life]
 (assoc life :buffkeys (cons buff-key (:buffkeys life))))

(def skills 
 {:vertical-chop 
   (spawn-skill :name "垂直四方斩"
                ; tested
                :produce-effect (fn [{src :src :as all}] (vertical-chop-effect src)))
  :once-shield
   (spawn-skill :name "寒冰屏障"
                ; tested
                :affect (fn [{tar :tar :as all}] (assoc all :tar (add-buff :once-shield tar))))})

